package org.dftproject.gedcom.core;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.util.LinkedList;
import java.util.List;

public class GedcomReader {
	
	private final List<IGedcomReaderListener> listeners = new LinkedList<IGedcomReaderListener>();

	public List<Line> read(Reader source) throws IOException {
		List<Line> rootLines = new LinkedList<Line>();
		
		BufferedReader reader = new BufferedReader(source);

		Line previous = null;

		String line;
		while ((line = reader.readLine()) != null) {
			Line current;

			try {
				current = new Line(line);
			} catch (IllegalArgumentException e) {
				System.err.println("Bad GEDCOM line: " + line);
				continue;
			}

			// Skip negative level numbers

			short level = current.getLevel();
			if (level < 0)
				continue;

			// Back up to the level one less than the current

			while (previous != null && level <= previous.getLevel())
				previous = previous.getParent();

			if (previous == null) {
				// Add only level 0 lines to the root; ignore others

				if (level != 0)
					continue;

				rootLines.add(current);
				previous = current;
			} else {
				// Add only lines that are level + 1; ignore others

				if (level != previous.getLevel() + 1)
					continue;
				
				previous.addLine(current);
				previous = current;
			}
			
			notifyLineAdded(current);
		}
		
		return rootLines;
	}
	
	public void addListener(IGedcomReaderListener listener) {
		listeners.add(listener);
	}
	
	public void removeListener(IGedcomReaderListener listener) {
		listeners.remove(listener);
	}
	
	protected void notifyLineAdded(Line line) {
		for (IGedcomReaderListener listener : listeners)
			listener.lineAdded(line);
	}

}
